// 三种宏定义语法的示例
// Patterns and Designators: 模式与设计器
// overloading: 重载
// Repetition: 重复

// --- designators ---
// The arguments of a macro are prefixed by a dollar sign $ and type annotated with a designator:
// 宏的参数前面带着美元符号$，并用类型注解来表示设计器：

macro_rules! create_function {
    // This macro takes an argument of designator `ident` and
    // creates a function named `$func_name`.
    // The `ident` designator is used for variable/function names.
    ($func_name:ident) => {
        fn $func_name() {
            // The `stringify!` macro converts an `ident` into a string.
            println!("You called {:?}()",
                     stringify!($func_name));
        }
    };
}

// Create functions named `foo` and `bar` with the above macro.
create_function!(foo);
create_function!(bar);

macro_rules! print_result {
    // This macro takes an expression of type `expr` and prints
    // it as a string along with its result.
    // The `expr` designator is used for expressions.
    ($expression:expr) => {
        // `stringify!` will convert the expression *as it is* into a string.
        println!("{:?} = {:?}",
                 stringify!($expression),
                 $expression);
    };
}

fn main() {
    foo();
    bar();

    print_result!(1u32 + 1);

    // Recall that blocks are expressions too!
    print_result!({
        let x = 1u32;

        x * x + 2 * x - 1
    });
}

// 还有如下designators：
/**
 * These are some of the available designators:

block
expr is used for expressions
ident is used for variable/function names
item
literal is used for literal constants
pat (pattern)
path
stmt (statement)
tt (token tree)
ty (type)
vis (visibility qualifier)
 */